#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
#else
using System.Windows;
using System.Windows.Controls;
#endif

namespace FreshMeat.Xaml
{
   /// <summary>
   /// A grid which automatically generates a specific number of rows and columns.
   /// </summary>
   public class DynaGrid : Grid
   {
      public readonly static DependencyProperty ColumnsProperty = DependencyProperty.Register(
         "Columns",
         typeof(int),
         typeof(DynaGrid),
         new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure, (d, e) => ((DynaGrid)d).Reconstruct()));

      public readonly static DependencyProperty RowsProperty = DependencyProperty.Register(
         "Rows",
         typeof(int),
         typeof(DynaGrid),
         new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure, (d, e) => ((DynaGrid)d).Reconstruct()));

      public readonly static DependencyProperty MinColumnWidthProperty = DependencyProperty.Register(
         "MinColumnWidth",
         typeof(double),
         typeof(DynaGrid),
         new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure, (d, e) => ((DynaGrid)d).Reconstruct()));

      public readonly static DependencyProperty MinRowHeightProperty = DependencyProperty.Register(
         "MinRowHeight",
         typeof(double),
         typeof(DynaGrid),
         new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure, (d, e) => ((DynaGrid)d).Reconstruct()));

      public readonly static DependencyProperty ColumnWidthProperty = DependencyProperty.Register(
         "ColumnWidth",
         typeof(GridLength),
         typeof(DynaGrid),
         new FrameworkPropertyMetadata(GridLength.Auto, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure, (d, e) => ((DynaGrid)d).Reconstruct()));

      public readonly static DependencyProperty RowHeightProperty = DependencyProperty.Register(
         "RowHeight",
         typeof(GridLength),
         typeof(DynaGrid),
         new FrameworkPropertyMetadata(GridLength.Auto, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure, (d, e) => ((DynaGrid)d).Reconstruct()));

#if NETFX_CORE
      protected override void OnApplyTemplate()
#else
      public override void OnApplyTemplate()
#endif
      {
         base.OnApplyTemplate();
         Reconstruct();
      }

      void Reconstruct()
      {
         if (ColumnDefinitions.Count != Columns)
            ColumnDefinitions.Clear();

         for (var i = 0; i < Columns; i++)
         {
            var column = new ColumnDefinition {Width = ColumnWidth, MinWidth = MinColumnWidth};
            if (i >= ColumnDefinitions.Count)
               ColumnDefinitions.Add(column);
            else
               ColumnDefinitions[i] = column;
         }

         if (RowDefinitions.Count != Rows)
            RowDefinitions.Clear();

         for (var i = 0; i < Rows; i++)
         {
            var row = new RowDefinition {Height = RowHeight, MinHeight = MinRowHeight};
            if (i >= RowDefinitions.Count)
               RowDefinitions.Add(row);
            else
               RowDefinitions[i] = row;
         }

         InvalidateArrange();
      }

      public int Columns
      {
         get { return (int)GetValue(ColumnsProperty); }
         set { SetValue(ColumnsProperty, value); }
      }

      public int Rows
      {
         get { return (int)GetValue(RowsProperty); }
         set { SetValue(RowsProperty, value); }
      }

      public double MinColumnWidth
      {
         get { return (double)GetValue(MinColumnWidthProperty); }
         set { SetValue(MinColumnWidthProperty, value); }
      }

      public double MinRowHeight
      {
         get { return (double)GetValue(MinRowHeightProperty); }
         set { SetValue(MinRowHeightProperty, value); }
      }

      public GridLength ColumnWidth
      {
         get { return (GridLength)GetValue(ColumnWidthProperty); }
         set { SetValue(ColumnWidthProperty, value); }
      }

      public GridLength RowHeight
      {
         get { return (GridLength)GetValue(RowHeightProperty); }
         set { SetValue(RowHeightProperty, value); }
      }
   }
}